package responsibilitychain

import "fmt"

type Manager interface {
	HaveRight(int) bool
	HandleFeeRequest(string, int) bool
}

type RequestChain struct {
	Manager
	next *RequestChain
}

func (rc *RequestChain) HaveRight(int) bool {
	return true
}

func (rc *RequestChain) HandleFeeRequest(name string, hasRight int) bool {
	if rc.Manager.HaveRight(hasRight) {
		return rc.Manager.HandleFeeRequest(name, hasRight)
	}

	if rc.next != nil {
		return rc.next.HandleFeeRequest(name, hasRight)
	}
	return false
}

func (rc *RequestChain) SetSuccessor(m *RequestChain) {
	rc.next = m
}

type ProjectManager struct {
}

func (pm *ProjectManager) HaveRight(money int) bool {
	return money < 500
}

func (pm *ProjectManager) HandleFeeRequest(name string, money int) bool {
	if name == "member" {
		fmt.Printf("Project Manager has right: %v: %v\n", name, money)
		return true
	}
	fmt.Printf("Project Manager has no right: %v: %v\n", name, money)
	return false
}

func NewProjectManager() *RequestChain {
	return &RequestChain{
		Manager: &ProjectManager{},
		next:    nil,
	}
}

type DepManager struct{}

func (dm *DepManager) HaveRight(money int) bool {
	return money < 5000
}

func (dm *DepManager) HandleFeeRequest(name string, money int) bool {
	if name == "admin" {
		fmt.Printf("Department Manager has right: %v: %v\n", name, money)
		return true
	}
	fmt.Printf("Department Manager has no right: %v: %v\n", name, money)
	return false
}

func NewDepManager() *RequestChain {
	return &RequestChain{
		Manager: &DepManager{},
		next:    nil,
	}
}

type GeneralManger struct {
}

func (gm *GeneralManger) HaveRight(int) bool {
	return true
}

func (gm *GeneralManger) HandleFeeRequest(name string, money int) bool {
	if name == "root" {
		fmt.Printf("General Manager has right: %v: %v\n", name, money)
		return true
	}
	fmt.Printf("General Manager has no right: %v: %v\n", name, money)
	return false
}

func NewGeneralManger() *RequestChain {
	return &RequestChain{
		Manager: &GeneralManger{},
		next:    nil,
	}
}
